//*************************************************************************
// File Name: CheckoutService.cpp
// This is the implementation file for the member functions
// of Class CheckoutService
// "Group 3"
// CS 1C
// March 25, 2010
// Group Project: SuperWarehouse
// Due: March 25, 2010
// - KZ's comment
//*************************************************************************

#include "CheckoutService.h"

//  private class members
//  *memberManager

CheckoutService::CheckoutService(MemberManager *m) :
	memberManager(m) {
}

CheckoutService::~CheckoutService() {
}

bool CheckoutService::processDailySalesFromFile(string fileName) {
	ifstream inFile;
	TransactionList *superTrans, *basicTrans;
	Transaction *currTrans;
	SaleItemList *dailySales;
	SaleItemList::SaleItem currSale;
	char tempDate[200];
	//string dateStr;
	char tempItemName[200];
	char buf[200];
	string itemName;
	time_t transDate, firstTransDate;
	int custNum, qty;
	float price;
	MemberList *allMembers, *basicMembers, *superMembers;
	Member *currMember;
	ReportingService *reporter;

	debugMsg(string(string("Filename: ") + fileName).c_str());

	allMembers = memberManager->getAllMembers();

	if (!allMembers->getNumMembers()) {
		errorMsg("Members database is empty; cannot process sales.");
		return false;
	}

	dailySales = new SaleItemList();
	superTrans = new TransactionList();
	basicTrans = new TransactionList();
	superMembers = new MemberList();
	basicMembers = new MemberList();

	inFile.open(fileName.c_str());
	if (inFile.fail()) {
		return false;
	}

	firstTransDate = 0;

	statusMsg("Processing sales file");

	while (!inFile.eof() && !inFile.fail()) {
		inFile.getline(tempDate, 200);

		if (strlen(tempDate) == 0) {
			break;
		}

		transDate = timestampFromDateString(string(tempDate));
		if (firstTransDate == 0) {
			firstTransDate = transDate;
		}

		inFile >> custNum;
		inFile.ignore(5, '\n');
		inFile.getline(tempItemName, 200);
		itemName = string(tempItemName);
		chomp(itemName);
		inFile >> price;
		inFile.ignore(5, '\t');
		inFile >> qty;
		inFile.ignore(5, '\n');

		currTrans = new Transaction(transDate, custNum, itemName, price, qty);
		dailySales->addItem(itemName, price, qty);

		currMember = allMembers->findMemberById(custNum);

		if (currMember->getMemberType() == MEMBER_CODE_BASIC) {
			// Add member to list
			if (superMembers->findMemberById(
					currMember->getMemberNumber()) == NULL) {
				superMembers->addMember(currMember);
			}
			superTrans->addTransaction(currTrans);
		} else {
			if (basicMembers->findMemberById(
					currMember->getMemberNumber()) == NULL) {
				basicMembers->addMember(currMember);
			}
			basicTrans->addTransaction(currTrans);
		}
	}

	sprintf(buf, "Processing %d Super Member transactions for %d members",
			superTrans->getNumTransactions(), superMembers->getNumMembers());
	statusMsg(buf);
	processTransactions(superTrans);

	sprintf(buf, "Processing %d Basic Member transactions for %d members",
			basicTrans->getNumTransactions(), basicMembers->getNumMembers());
	statusMsg(buf);
	processTransactions(basicTrans);

	statusMsg("Writing daily sales report");
	reporter = new ReportingService();
	reporter->writeSalesReportForDay(firstTransDate, dailySales,
			superMembers->getNumMembers(), basicMembers->getNumMembers());

	// Clean up
	delete superTrans;
	delete basicTrans;

	return true;
}

void CheckoutService::processTransactions(TransactionList *transactions) {
	int i, n;
	Member *m;
	Transaction *t;
	char buf[200];

	n = transactions->getNumTransactions();

	for (i = 0; i < n; i++) {
		t = transactions->retrieveTransactionAtIndex(i);
		m = memberManager->getAllMembers()->findMemberById(t->getCustID());
		if (m == NULL) {
			sprintf(buf, "Error processing transaction; unable to find customer %d", t->getCustID());
			errorMsg(buf);
			continue;
		}
		m->addPurchase(t->getPrice() * t->getQty());
	}
}

